package com.cxx.purchasecharge.core.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;

public class PurchaseChargeProperties extends Properties
{
    private static final long serialVersionUID = 1L;
    private static final Logger logger = Logger.getLogger (PurchaseChargeProperties.class);
    private static final String PURCHASE_CHARGE_PROPERTIES_FILE = "pc-core-config.properties";

    private static PurchaseChargeProperties purchaseChargeProperties = getInstance ();

    private PurchaseChargeProperties ()
    {
        String cxxPropertiesDir = BaseConfigUtil.getCfxPropertiesDir ();
        InputStream inputStream = null;

        if (cxxPropertiesDir != null && !"".equals (cxxPropertiesDir))
        {
            cxxPropertiesDir = cxxPropertiesDir.trim ();
            if (!cxxPropertiesDir.endsWith (File.separator))
            {
                cxxPropertiesDir += File.separator;
            }
            cxxPropertiesDir += PURCHASE_CHARGE_PROPERTIES_FILE;
            logger.info (PURCHASE_CHARGE_PROPERTIES_FILE + " file path is " + cxxPropertiesDir);

            try
            {
                inputStream = new FileInputStream (cxxPropertiesDir);
                // load (inputStream);
                load (new InputStreamReader (inputStream, "UTF-8"));
                
                validateProperties (this);
            }
            catch (FileNotFoundException e)
            {
                logger.warn ("Can't find " + PURCHASE_CHARGE_PROPERTIES_FILE, e);
            }
            catch (IOException e)
            {
                logger.warn ("Can't load " + PURCHASE_CHARGE_PROPERTIES_FILE, e);
            }
        }
        else
        {
            logger.warn ("Can't find properties directory.");
        }
    }

    private Properties validateProperties (Properties properties)
    {
        List <String> errors = new ArrayList <String> ();

        // check for mandatory and complete properties with default values when
        // missing
        for (ConfigurationProperties confProps : ConfigurationProperties.values ())
        {
            if (properties.get (confProps.getName ()) == null)
            {
                if (confProps.isMandatory ())
                {
                    errors.add ("The mandatory Property '" + confProps.getName () + "' is not set.");
                }
                else if (confProps.getDefaultValue () != null)
                {
                    properties.setProperty (confProps.getName (), confProps.getDefaultValue ());
                }
            }
        }

        if (!errors.isEmpty ())
        {
            logger.error (errors.toString ());
            throw new IllegalArgumentException (errors.toString ());
        }

        return properties;
    }

    private static synchronized PurchaseChargeProperties getInstance ()
    {
        if (purchaseChargeProperties == null)
        {
            purchaseChargeProperties = new PurchaseChargeProperties ();
        }
        return purchaseChargeProperties;
    }

    public static String getDbDriver ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.JPA_DB_DRIVER.getName ());
    }

    public static String getDbUrl ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.JPA_DB_URL.getName ());
    }

    public static String getDbInstance ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.JPA_DB_INSTANCE.getName ());
    }

    public static String getDbUser ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.JPA_DB_USER.getName ());
    }

    public static String getDbPassword ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.JPA_DB_PASSWORD.getName ());
    }

    public static String getMockAdmin ()
    {
        return purchaseChargeProperties.getProperty ("mock.user.admin");
    }

    public static String getMockUser ()
    {
        return purchaseChargeProperties.getProperty ("mock.user.user");
    }

    public static String getMockAdminRole ()
    {
        return purchaseChargeProperties.getProperty ("mock.role.admin");
    }

    public static String getMockUserRole ()
    {
        return purchaseChargeProperties.getProperty ("mock.role.user");
    }

    public static String getDefaultPassword ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.PC_DEFAULT_PASSWORD.getName ());
    }

    public static boolean getInitUserFlag ()
    {
        return Boolean.parseBoolean (purchaseChargeProperties.getProperty (ConfigurationProperties.PC_INIT_USER_FLAG.getName ()));
    }

    public static String getAddInorderPaidComment ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.PC_INORDER_ADDPAID_COMMENT.getName ());
    }

    public static String getDelInorderPaidComment ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.PC_INORDER_DELPAID_COMMENT.getName ());
    }

    public static String getAddOutorderPaidComment ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.PC_OUTORDER_ADDPAID_COMMENT.getName ());
    }

    public static String getDelOutorderPaidComment ()
    {
        return purchaseChargeProperties.getProperty (ConfigurationProperties.PC_OUTORDER_DELPAID_COMMENT.getName ());
    }

    public static int getViewPaidDaysForSalesman ()
    {
        return Integer.parseInt (purchaseChargeProperties.getProperty (ConfigurationProperties.PC_SALESMAN_VIEWPAID_DAYS.getName ()));
    }

}
